<template>
  <div class="component-info">
    <div class="component-info-table-opt" v-if="showAdd">
      <a-button @click="rowPlus">添加</a-button>
    </div>
    <div class="component-info-table">
        <a-table
          :columns="extendColumns"
          :data-source="dataToSubmit"
          :pagination="false"
          :scroll="scroll"
          tableLayout="fixed"
          size="large"
        >
          <template
            v-for="(item, columnIndex) in inputCells"
            slot-scope="text, record, index"
            :slot="item.dataIndex"
          >
           <a-form-model
            :model="dataToSubmit[index]"
            :key="item.index"
            :ref="`${item.dataIndex}-${index}`"
            :rules="tableRules"
            layout="inline"
            >
            <a-form-model-item :prop="item.dataIndex">
              <a-input
                :name="record.key"
                v-if="item.type === 'input'"
                v-model="dataToSubmit[index][item.dataIndex]"
                :disabled = "actionType === 'preview'"
                :placeholder="item.placeholder"
                @change="(e,event) => onChange(e, record, index, columnIndex,event)"
                :key="item.index"
                :maxLength="item.maxLength"
              />
              <a-textarea
                :name="record.key"
                v-if="item.type === 'textarea'"
                v-model="dataToSubmit[index][item.dataIndex]"
                :disabled = "actionType === 'preview'"
                :placeholder="item.placeholder"
                @change="(e,event) => onChange(e, record, index, columnIndex,event)"
                :key="item.index"
                :maxLength="item.maxLength"
              />
              <a-date-picker
                :name="record.key"
                v-if="item.type === 'date'"
                v-model="dataToSubmit[index][item.dataIndex]"
                :show-time="item.format ? true: false"
                :format="item.format ? item.format : ''"
                :valueFormat="item.format ? item.format : 'YYYY-MM-DD'"
                :disabled = "actionType === 'preview'"
                :placeholder="item.placeholder"
                @change="(e,event) => onChange(e, record, index, columnIndex,event)"
                :key="item.index"
              />
              <a-select
                v-model="dataToSubmit[index][item.dataIndex]"
                :placeholder="item.placeholder"
                :disabled = "actionType === 'preview'"
                @change="(e,event) => onChange(e, record, index, columnIndex,event)"
                :key="item.key"
                v-if="item.type === 'select' && item.dataIndex === 'supplierCode'"
                style="width:100px"
              >
                <a-select-option
                  v-for="item in optionMaps[index]"
                  :key="item.value"
                >
                  {{ item.text }}
                </a-select-option>
              </a-select>
              <a-select
                v-model="dataToSubmit[index][item.dataIndex]"
                :placeholder="item.placeholder"
                :disabled = "actionType === 'preview'"
                @change="(e,event) => onChange(e, record, index, columnIndex,event)"
                :key="item.key"
                v-if="item.type === 'select' && item.dataIndex !== 'supplierCode'"
                style="width:100px"
              >
                <a-select-option
                  v-for="item in inputCells[columnIndex].options"
                  :key="item.value"
                >
                  {{ item.text }}
                </a-select-option>
              </a-select>
            </a-form-model-item>
           </a-form-model>
          </template>
          <template slot-scope="text, record, index" slot="opt" >
            <a-icon
              type="minus-circle"
              theme="twoTone"
              @click="(e) => rowMinus(e, index)"
            />
          </template>
        </a-table>
    </div>
  </div>
</template>

<script>
import { CODE_SUCCESS } from '@/utils/consts';
import { getApi } from '@/services/autoApi';
import { postApi } from '../../services/autoApi';
import { vehicleAndpartsWarrCalcInputs } from '../input-panel/basicBlock';

export default {
  name: 'componentInfo',
  data() {
    return {
      optionMaps: [],
      partsSourceOption: [],
      dataToSubmit: [],
      dataToSubmitRow: {},
      rules: [{ required: true, message: '请填写' }]
    };
  },

  props: {
    formModel: {
      type: Object,
      default() {
        return {};
      }
    },
    columns: {
      type: Array,
      default() {
        return [];
      }
    },
    relatedFormModel: {
      type: String,
      default() {
        return 'workPartsList';
      }
    },
    partsSource: {
      type: Number,
      default() {
        return 1;
      }
    },
    actionType: {
      type: String,
      default() {
        return 'add';
      }
    },
    apiData: {
      type: Object,
      default() {
        return {};
      }
    },
    showAdd: {
      type: Boolean,
      default() {
        return true;
      }
    },
    scroll: {
      type: Object,
      default() {
        return { x: 1000 };
      }
    }
  },
  watch: {
    apiData(val) {
      Array
        .prototype
        .forEach
        .call(this.columns, (item) => {
          (0, this.dataToSubmitRow)[item.key] = undefined;
          if (item.init) {
            item.init(this);
          }
        });
      this.dataToSubmit = Array
        .prototype
        .map
        .call(
          (val)[this.relatedFormModel] || [],
          (item) => ({ ...item })
        );
      this.watchTableAmountChange();
      // this.dataToSubmit.push({ ...this.dataToSubmitRow });
    },
    dataToSubmit(val) {
      if (val === (0, this.formModel)[this.relatedFormModel]) return;
      this.tableDataChangeNotify();
    }
  },
  computed: {
    inputCells() {
      return Array
        .prototype
        .filter
        .call(
          this.columns,
          (item) => item.type !== undefined
        );
    },
    extendColumns() {
      return Array.prototype.map.call(
        this.columns,
        (item) => ({ ...item, width: 200 })
      );
    },
    tableRules() {
      const res = {};
      Array
        .prototype
        .forEach
        .call(this.columns, (item) => {
          if (item.rules && item.rules.length > 0) {
            item
              .rules
              .forEach((rule, index) => {
                if (rule.validator) {
                  item.rules[index].validator.vue = this;
                }
              });
            res[item.dataIndex] = item.rules;
          }
        });
      return res;
    }
  },
  methods: {
    rowPlus() {
      if (this.isPreview()) return;
      this.dataToSubmit.push({ ...this.dataToSubmitRow });
      this.watchTableAmountChange();
    },
    rowMinus(e, index) {
      if (this.isPreview()) return;
      // if (this.dataToSubmit.length === 1) {
      //   this.$message.warning('最后一条请勿删除');
      //   return;
      // }
      this.dataToSubmit.splice(index, 1);
      this.optionMaps.splice(index, 1);
    },
    tableDataChangeNotify() {
      this.$emit(
        'componentInfoUpdate',
        this.relatedFormModel,
        this.dataToSubmit
      );
    },
    updateFormModel(key, val) {
      this.$emit(
        'componentInfoUpdate',
        key,
        val
      );
    },
    onChange(e, record, index, columnIndex, event) {
      if (!(0, this.inputCells)[columnIndex].onChange) return;
      (0, this.inputCells)[columnIndex].onChange.call(
        this,
        e,
        record,
        index,
        columnIndex,
        event
      );
    },
    async getCompnentInfo(params, index, columnIndex) {
      this.beforeHook(params, index, columnIndex);
      const { getDataUrl } = (0, this.inputCells)[columnIndex];
      await getApi(getDataUrl, params).then((res) => {
        const { code, message, data } = res.data;
        if (code === CODE_SUCCESS) {
          const keys = Object.keys(this.dataToSubmit[index]);
          const newDataToSubmitRow = {};
          Array.prototype.forEach.call(keys, (item) => {
            newDataToSubmitRow[item] = data[item];
          });
          this.dataToSubmit.splice(index, 1, { ...newDataToSubmitRow });
          this.afterHook(params, index, data, columnIndex);
          return;
        }
        this.$message.error(message);
      });
    },
    beforeHook(param, index, columnIndex) {
      if (!(0, this.inputCells)[columnIndex].beforeHook) return true;
      return (0, this.inputCells)[columnIndex].beforeHook.call(
        this,
        param,
        index
      );
    },
    afterHook(param, index, data, columnIndex) {
      if (!(0, this.inputCells)[columnIndex].afterHook) return;
      (0, this.inputCells)[columnIndex].afterHook.call(
        this,
        param,
        index,
        data
      );
    },
    formatParam(index, columnIndex) {
      const params = {};
      const { paramStruct, formModelKey } = (0, this.inputCells)[columnIndex];
      const paramKeys = Object.keys(paramStruct);
      Array
        .prototype
        .forEach
        .call(paramKeys, (item) => {
          params[item] = (0, this.dataToSubmit)[index][item] || paramStruct[item];
          if (formModelKey
            && Object.keys(formModelKey).includes(item)
            && (0, this.formModel)[item]
          ) {
            params[item] = (0, this.formModel)[item];
          }
        });
      return params;
    },
    isPreview() {
      return this.actionType === 'preview';
    },
    watchTableAmountChange() {
      this.dataToSubmit.forEach((item, index) => {
        const watchFlag = {
          workWorkingHourList: 'hourlyFee',
          workPartsList: 'money',
          orderInfos: 'money'
        };
        this.$watch(`dataToSubmit.${index}.${watchFlag[this.relatedFormModel]}`, (oldval, newVal) => {
          if (oldval !== newVal) {
            const fee = this.dataToSubmit
              .filter((it) => it[watchFlag[this.relatedFormModel]] > 0)
              .map((it) => ({ fee: it[watchFlag[this.relatedFormModel]], countType: 1 }));
            postApi('/workOrder/countFee', fee).then((res) => {
              const { code, message, data } = res.data;
              if (code !== CODE_SUCCESS) {
                this.$message.error(message);
                return;
              }
              if (this.relatedFormModel === 'workPartsList') this.updateFormModel('accessoriesFee', data);
              if (this.relatedFormModel === 'workWorkingHourList') this.updateFormModel('hourlyFee', data);
              if (this.relatedFormModel === 'orderInfos') this.updateFormModel('orderAmount', data);
              postApi('/workOrder/countFee', vehicleAndpartsWarrCalcInputs.call(this))
                .then((totalRes) => {
                  if (totalRes.data.code !== CODE_SUCCESS) return;
                  this.updateFormModel('totalCost', totalRes.data.data);
                });
            });
          }
        });
      });
    },
    tableFormValidate() {
      const flags = [];
      Array
        .prototype
        .forEach
        .call(this.dataToSubmit, (dataItem, dataIndex) => {
          this
            .inputCells
            .forEach((columnItem) => {
              const ref = `${columnItem.dataIndex}-${dataIndex}`;
              this.$refs[ref][0].validate((passed) => {
                flags.push(passed);
              });
            });
        });

      if (flags.includes(false)) {
        throw new Error('字段验证失败');
      }
    }
  }
};
</script>
<style lang="less" scoped>
.component-info-table-opt {
  padding-bottom: 1rem;
}
</style>
